package tech.yunland.shop.domain.service;

import com.moyuer.bsf.domain.dao.OrganDao;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.yunland.shop.domain.dao.ReserveDao;
import tech.yunland.shop.domain.dao.ReserveEntryDao;
import tech.yunland.shop.domain.dao.SNGenerator;
import tech.yunland.shop.domain.model.Reserve;
import tech.yunland.shop.domain.model.ReserveEntry;

import java.util.List;

/**
 * 预约服务
 *
 * @author: 袁首京<yuanshoujing@gmail.com> 16/4/19
 */
@Service
public class ReserveService {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    private static final String DELETE_ENTRIES_HQL = "delete from SaleBillEntry se where se.owner.id=?";

    @Autowired
    private ReserveDao reserveDao;

    @Autowired
    private ReserveEntryDao reserveEntryDao;

    @Autowired
    private SNGenerator snGenerator;

    @Autowired
    private OrganDao organDao;

    /**
     * 保存预约
     *
     * @param reserve
     * @Return void
     */
    public void saveOrUpdate(Reserve reserve) {
        if (reserve.getSn() == null) {
            String sn = snGenerator.gen("reserve", reserve.getOrganId());
            reserve.setSn(sn);
        }
        reserveDao.saveOrUpdate(reserve);

        // 清理旧分录
        reserveEntryDao.bulkUpdate(DELETE_ENTRIES_HQL, reserve.getId());
        if (reserve.getEntries() != null) {
            // 保存新分录
            for (ReserveEntry reserveEntry : reserve.getEntries()) {
                reserveEntryDao.save(reserveEntry);
            }
        }
    }

    /**
     * 追加分录
     *
     * @param entry
     */
    public void addEntry(ReserveEntry entry) {
        reserveEntryDao.save(entry);
    }

    /**
     * 根据主键ID获取一条预约
     *
     * @param id
     * @Return void
     */
    public Reserve get(String id) {
        return reserveDao.get(id);
    }

    /**
     * 根据主键ID删除一条预约
     *
     * @param reserve 预约
     * @Return void
     */
    public void delete(Reserve reserve) {
        if (reserve.getState() == -1) {
            return;
        }

        reserve.setState(-1);
        reserveDao.update(reserve);
    }

    /**
     * 查询结果sql
     *
     * @param states 状态组
     * @Return HqlArgs
     */
    private DetachedCriteria getCriteria(List<Integer> states, List<String> organIds) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Reserve.class);

        if (states != null && states.size() > 0) {
            if (states.size() == 1) {
                criteria.add(Restrictions.eq("state", states.get(0)));
            }
            else {
                criteria.add(Restrictions.in("state", states));
            }
        }

        if (organIds != null && organIds.size() > 0) {
            if (organIds.size() == 1) {
                criteria.createCriteria("organ").add(Restrictions.idEq(organIds.get(0)));
            }
            else {
                criteria.createCriteria("organ").add(Restrictions.in("id", organIds));
            }
        }

        return criteria;
    }

    /**
     * 读取符合条件预约
     *
     * @param states 状态组
     * @Return int
     */
    public int getResultSize(List<Integer> states, List<String> organIds) {
        DetachedCriteria criteria = getCriteria(states, organIds);
        return reserveDao.findByCriteria(criteria).size();
    }

    /**
     * 读取符合条件的预约
     *
     * @param states   状态组
     * @param startIdx
     * @param length
     * @Return List<Reserve>
     */
    public List<Reserve> getResultInfos(List<Integer> states, Integer startIdx, Integer length, List<String> organIds) {
        DetachedCriteria criteria = getCriteria(states, organIds);
        criteria.addOrder(Order.desc("createTime"));
        return reserveDao.findByCriteria(criteria, startIdx, length);
    }
}
